
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections;
using System.Runtime.Serialization;
using System.Text;
using System.Xml;

using Swaf.Resource;
using Swaf.Call;

namespace Swaf
{
	/// <summary>
	/// The basic implementation of IResults that is used by <c>RuleManager</c>
	/// to return the results of calling business rules.</summary>
	/// <author>mdenman</author>
	public class BasicResults : MarshalByRefObject, IResults
	{
		protected IList m_calls;

		protected static string s_baseXmlFormat = 
			"<RuleCallResults>{0}</RuleCallResults>";
		protected static string s_baseResultXmlFormat =
			"<CallResults>{0}</CallResults>";
		protected static string s_baseExceptionXmlFormat =
			"<Exception>{0}</Exception>";
		protected static int s_initialBuffSize = 512;
		public virtual object CallResults
		{
			get
			{
				return getCallResults(0);
			}
			
		}
		public virtual Exception ExceptionInfo
		{
			get
			{
				return getExceptionInfo(0);
			}
			
		}
		
		public BasicResults()
		{
			m_calls = new ArrayList();
		}
		
		public BasicResults(object callResults):this(callResults, null)
		{
		}
		
		public BasicResults(Exception e):this(null, e)
		{
		}
		
		public BasicResults(object callResults, Exception errInfo):this()
		{
			add(callResults, errInfo);
		}
		public static BasicResults createFromXml(XmlElement resultsXml)
		{
			BasicResults br = new BasicResults();
			XmlNodeList l = resultsXml.ChildNodes;
			for(int pos = 0; pos < l.Count; ++pos)
			{
				XmlElement el = (XmlElement)l.Item(pos);
				if(el.Name.Equals("CallResult"))
				{
					br.add(Serialization.deserialize(el.GetAttribute("type"), el.InnerText), null);
				}
				else if(el.Name.Equals("Exception"))
				{
					br.add(null, new Exception(el.InnerText));
				}
				else
				{
					//TODO Throw an exception for bad formatting of xml.
				}
			}
			return br;
		}
		
		public virtual SingleCallAndResult add(object callResults, Exception errInfo)
		{
			SingleCallAndResult c = new SingleCallAndResult(callResults, errInfo);
			m_calls.Add(c);
			return c;
		}

		public virtual SingleCallAndResult add(SingleCallAndResult c)
		{
			m_calls.Add(c);
			return c;
		}

		public virtual SingleCallAndResult add(ICall call)
		{
			SingleCallAndResult c = new SingleCallAndResult(call);
			m_calls.Add(c);
			return c;
		}

		public SingleCallAndResult this[int index]
		{
			get
			{
				return (SingleCallAndResult)m_calls[index];
			}
		}
		
		public virtual object getCallResults(int pos)
		{
			if (m_calls.Count > pos)
				return this[pos].CallResults;
			else
				return null;
		}
		
		public virtual Exception getExceptionInfo(int pos)
		{
			if (m_calls.Count > pos)
				return this[pos].ExceptionInfo;
			else
				return null;
		}

		public string getXml()
		{
			IResourceManager resMgr = Application.currentApp.resMgr;
			StringBuilder buf = new StringBuilder(s_initialBuffSize);
			buf.Append("<RuleCallResults>\n");
			
			foreach(SingleCallAndResult c in m_calls)
			{
				if(c.CallResults != null)
				{
					SerializationInfo sinfo = Serialization.serialize(c.CallResults);
					buf.Append("<CallResult type='").Append(sinfo.TypeName).Append("'>");
					buf.Append(resMgr.fixupForXml(sinfo.SerialObject));
					buf.Append("</CallResult>\n");
				}
				else if(c.ExceptionInfo != null)
				{
					buf.Append("<Exception>\n").Append(resMgr.fixupForXml(c.ExceptionInfo.ToString())).Append("</Exception>\n");
				}
			}
			buf.Append("</RuleCallResults>\n");
			return buf.ToString();
		}

		public virtual int numberOfResults
		{get{
			return m_calls.Count;
		}}
		
	
	}
}